package de.ur.iw.wiki;

import java.util.ArrayList;

import de.ur.iw.interfaces.PathListener;
import de.ur.iw.wiki.weighters.BasicWeighter;

public class PathThread extends Thread {

	private int maxLength;
	private ArrayList<WikiPage> path = new ArrayList<WikiPage>();
	private Weighter weighter = new BasicWeighter();

	private ArrayList<PathListener> listeners = new ArrayList<PathListener>();

	public PathThread(int maxLength, Weighter weighter) {
		this.maxLength = maxLength;
		this.weighter = weighter;
	}

	public PathThread(int maxLength) {
		this.maxLength = maxLength;
	}

	@Override
	public void run() {
		try {
			// use the saved start-page as start for the path
			String current = Settings.getString(Settings.KEY_START_PAGE, null);
			if (current == null) {
				current = WikiDownloader.getRandomName();
			} else {
				// choose a random page to start if the saved start-page doesnt
				// exist
				WikiPage page = WikiDownloader.download(current);
				if (page == null) {
					current = WikiDownloader.getRandomName();
				}
			}
			while (path.size()<maxLength) {
				WikiPage page = WikiDownloader.download(current);

				if (weighter != null) {
					page.weight(weighter);
				}

				// add the page if its not in the path already (only if you dont
				// have "prevent_loops" turned on")
				if (!path.contains(page)
						|| !Settings.getBoolean(Settings.KEY_PREVENT_LOOPS,
								false)) {
					path.add(page);
				} else {
					// get another random page otherwhise
					current = path.get(path.size() - 1)
							.getRandomWeightedArticle().toString();
				}
				if (page.size() == 0) {
					// if a dead end is reached and the "prevent_dead_end"
					// setting is enabled go back one step
					if (Settings.getBoolean(Settings.KEY_DEAD_END, false)) {
						path.remove(path.size()-1);
						if(path.size()<=1){
							break;
						}
						current = path.get(path.size()-1).getName();
						path.remove(path.size()-1);
						System.err.println(page.getName()+" has no more links, going back one step!");
					} else {
						System.err.println(page.getName()+" has no more links!");
						break;
					}
				} else {
					current = page.getRandomWeightedArticle().toString();
				}
			}
			System.out.println("Path with a size of "+path.size()+" done");
			done(path);

		} catch (Exception e) {
			e.printStackTrace();
			done(null);
		}
	}

	private void done(ArrayList<WikiPage> path) {
		notifyListeners(path);
	}

	private void notifyListeners(ArrayList<WikiPage> path) {
		for (PathListener p : listeners) {
			p.onPathCompleted(path);
		}
	}

	public void addPathListener(PathListener l) {
		if (!listeners.contains(l)) {
			listeners.add(l);
		}
	}

	public boolean removePathListener(PathListener l) {
		return listeners.remove(l);
	}

}
